package com.tbit.uqbike.tergateway.wa206pkg;


import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.annotation.JSONField;
import com.tbit.uqbike.TerGatewayMain;
import com.tbit.uqbike.protocol.ATerPkg;
import com.tbit.uqbike.protocol.AnalyzeImpl.AProtocol;
import com.tbit.uqbike.protocol.AnalyzeImpl.WA206DeEnCoder;
import com.tbit.uqbike.service.ice.icebase.CellIdManage.DPoint;
import com.tbit.uqbike.service.ice.impl.CellIdManageImpl;
import com.tbit.uqbike.tergateway.config.TerGatewayConfig;
import com.tbit.uqbike.tergateway.data.TerGatewayData;
import com.tbit.uqbike.tergateway.entity.AConnInfo;
import com.tbit.uqbike.tergateway.entity.TerTempData;
import com.tbit.uqbike.tergateway.pojo.TerBattery;
import com.tbit.uqbike.tergateway.pojo.TerPos;
import com.tbit.uqbike.tergateway.wa206pkg.extend.CarStatusHelper;
import com.tbit.uqbike.tergateway.wa206pkg.extend.StatusHelper;
import com.tbit.uqbike.util.*;
import com.tbit.utils.BitUtil;
import io.netty.buffer.ByteBuf;

import java.util.Date;

/**
 * Created by MyWin on 2017/4/27.
 */
public class PosInfo extends ATerPkg {
    private static org.slf4j.Logger logger = org.slf4j.LoggerFactory.getLogger(PosInfo.class);

    @JSONField(name = "时间", format = "yyyy-MM-dd HH:mm:ss")
    public Date dt;
    @JSONField(name = "经度")
    public double lon;
    @JSONField(name = "纬度")
    public double lat;
    @JSONField(name = "高度")
    public int high;
    @JSONField(name = "角度")
    public int dir;
    @JSONField(name = "定位精度")
    public int pointUnit = -1;
    @JSONField(name = "信号强度")
    public int signalLevel = -1;
    @JSONField(name = "速度")
    public int speed;
    @JSONField(name = "信号状态")
    public int signalStatus;

    @JSONField(name = "信号状态解析")
    public String getSignalStatusStr() {
        return String.format("定位标志:%d,GPS:%d,POWER:%d,GSM:%d",
                signalStatus & 3,
                BitUtil.between(signalStatus, 2, 6),
                BitUtil.between(signalStatus, 6, 10),
                BitUtil.between(signalStatus, 10, 14)
        );
    }

    @JSONField(name = "国家码")
    public int mcc;
    @JSONField(name = "运营商码")
    public int mnc;
    @JSONField(name = "小区码")
    public int lac;
    @JSONField(name = "基站号")
    public int cellid;

    @JSONField(name = "相对SOC", serialize = false)
    public int soc;
    @JSONField(name = "SOH")
    public int soh;
    @JSONField(name = "充放电次数")
    public int dischargeCnt;
    @JSONField(name = "骑行电流")
    public int movingEI;
    @JSONField(name = "控制器温度")
    public int controlTemp;
    @JSONField(name = "电瓶电压")
    public int powEU;
    @JSONField(name = "总里程")
    public int totalMile;
    @JSONField(name = "单次里程")
    public int signMile;
    @JSONField(name = "霍尔速度")
    public int hallSpeed;
    @JSONField(name = "终端状态")
    public int terStatus;

    @JSONField(name = "终端状态解析")
    public String getTerStatusStr() {
        return StatusHelper.analyzeStatus(terStatus, CarStatusHelper.bitNameList);
    }

    /**
     * 可用剩余容量
     */
    @JSONField(name = "可用剩余容量")
    public Integer batteryRemaining;

    public Short batteryRelativelyRemaining;

    @Override
    public void doBusiness() {
        if (TerGatewayConfig.bHandlePos) {
            //logger.info(this.toString());
            TerTempData terTempData = TerGatewayData.getTerTempDataByMno(this.mno);
            TerPos terLastPos = terTempData.getLastPos();
            // 获取电量对象
            TerBattery newterBattery = getTerBattery();
            // 处理电量
            TerGatewayMain.terEvnet.terRecvNewBattery(terTempData, newterBattery);
            // 先判断是否合法，不合法直接过滤掉不处理
            TerPos newPos = getTerPos(terLastPos);
            int code = ErrorCode.OK;
            // 判断经纬度合法性
            if (!newPos.isLatlonOk()) {
                code = ErrorCode.ErrorLngLatError;
            } else {
                code = TerGatewayMain.terEvnet.terRecvNewPos(terTempData, newPos);
                // 更新电压
                terTempData.updateVol(this.dt, powEU);
            }
            if (code != ErrorCode.OK) {
                logger.info(String.format("由于:[%s]过滤掉轨迹:[%s]", ErrorCode.ErrorString(code), newPos.toString()));
            }
        }
    }

    @Override
    public boolean autoRsp() {
        return true;
    }

    public static String getPosPushMsg(TerPos terPos) {
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("msgId", ConstDefine.MQ_MSG_ID_POS_PUSH);
        jsonObject.put("feedback", StringUtil.Empty);
        jsonObject.put("data", terPos);
        return jsonObject.toJSONString();
    }

    @Override
    public ByteBuf getRsp(AConnInfo info, AProtocol protocol) {
        return ((WA206DeEnCoder) protocol).getPosInfoRsp(info, this);
    }

    private TerPos getTerPos(TerPos terLastPos) {
        TerPos terPos = new TerPos();
        terPos.setDir(this.dir);
        terPos.setDt(this.dt);
        terPos.setExData(StringUtil.Empty);
        terPos.setHigh(this.high);
        terPos.setMachineNO(this.mno);
        terPos.setSpeed(this.speed);
        terPos.setLat(this.lat);
        terPos.setLon(this.lon);
        terPos.setMile(this.signMile);
        terPos.setCarStatus(this.terStatus);

        terPos.signalStatus = this.signalStatus;
        terPos.signMile = this.signMile;
        terPos.hallSpeed = this.hallSpeed;
        terPos.wa206c = ((WA206Head) head).isWA206CVersion();
        terPos.lacId = String.format("%d.%d.%d", this.mcc, this.mnc, this.lac);
        terPos.cellId = Integer.toString(this.cellid);

        int pointType = this.signalStatus & 0x3;
        terPos.setPointType(pointType);
        // 进行小区定位
        if (!terPos.isSatellite()) {
            DPoint dPoint = null;
            try {
                dPoint = CellIdManageImpl.GetDpByCellId(String.format("%d.%d.%d.%d", this.mcc, this.mnc, this.lac, this.cellid));
            } catch (Exception e) {
                logger.error("CellIdManageImpl.GetDpByCellId", e);
            }
            if (null == dPoint) {
                pointType = ConstDefine.POINT_TYPE_UNKNOW;
            } else {
                pointType = ConstDefine.POINT_TYPE_CELL;
                terPos.setLon(dPoint.x);
                terPos.setLat(dPoint.y);
            }
        }
        terPos.setPointType(pointType);
        // 添加备注方法
        terPos.addExData("PU", Integer.toString(pointUnit));
        terPos.addExData("SL", Integer.toString(signalLevel));
        terPos.addExData("V", Integer.toString(powEU));
        return terPos;
    }

    private TerBattery getTerBattery() {
        TerBattery terBattery = new TerBattery();
        terBattery.setMachineNO(this.mno);
        terBattery.setDt(this.dt);
        terBattery.setBatteryEU(this.powEU);
        terBattery.setSoh(this.soh);
        terBattery.setSoc(this.soc);
        terBattery.setDischargeCnt(this.dischargeCnt);
        if (this.batteryRemaining != null) {
            terBattery.setBatteryRemaining(batteryRemaining);
        }
        if (this.batteryRelativelyRemaining != null) {
            terBattery.setBatteryRelativelyRemaining(batteryRelativelyRemaining);
        }
        return terBattery;
    }
}
